
// Define the global namespace for the application and the functions/methods within it (in case it's not already set)
if (!window.FrontSuite) FrontSuite = {};
if (!FrontSuite.util) FrontSuite.util = {};
if (!FrontSuite.util.ext) FrontSuite.util.ext = {};

FrontSuite.util.ext.login = function (user_token, password, duration, callback) {
    var apps_urldir             = FrontSuite.options.apps_urldir;
    var client_connection_token = FrontSuite.connection.client_connection_token;
    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/auth/user_auth_info',
        params    : {'user_token' : user_token, 'client_connection_token' : client_connection_token},
        autoAbort : false,
        method    : 'POST',
        scope     : this,
        success : function(response) {
            var user_auth_info_response = Ext.JSON.decode(response.responseText);
            var user_salt           = user_auth_info_response.user_salt;
            var algorithm           = user_auth_info_response.algorithm;
            var algorithm_option    = user_auth_info_response.algorithm_option;
            var current_date        = new Date();
            var current_time        = current_date.getTime();              // returns milliseconds since 1970-01-01 00:00:00 UTC
            var session_expire_time = current_time + duration*3600*1000;   // expire in the specified number of hours
            var session_expire_date = new Date(session_expire_time);
            var session_expire_dttm = session_expire_date.toISOString();
            session_expire_dttm     = session_expire_dttm.replace(/\.[0-9]+Z$/,'');
            session_expire_dttm     = session_expire_dttm.replace(/T/,' ');
            var password_hash       = FrontSuite.util.makePasswordHash(algorithm, algorithm_option, password, user_salt);
            var auth_token          = FrontSuite.util.makeAuthToken(password_hash, session_expire_dttm, client_connection_token);
            Ext.Ajax.request({
                url       : apps_urldir+'/sitefront/front-framework/api.php/service/auth/login',
                params    : {'user_token': user_token, 'session_expire_dttm': session_expire_dttm, 'auth_token': auth_token, 'option': 'authdata'},
                autoAbort : false,
                method    : 'POST',
                scope     : this,
                success : function(response){
                    var json_response  = Ext.JSON.decode(response.responseText);
                    if (json_response.success && json_response.user.user_token != 'guest') {
                        FrontSuite.session.user_token          = user_token;
                        FrontSuite.session.session_expire_dttm = session_expire_dttm;
                        FrontSuite.session.auth_token          = auth_token;
                        FrontSuite.session.group_id            = json_response.user.group_id;
                        FrontSuite.session.app_id              = json_response.user.app_id;
                        if (FrontSuite.session.authdata)       delete FrontSuite.session.authdata;
                        FrontSuite.session.authdata            = json_response;
                        if (callback) (callback)(true);
                        else FrontSuite.util.ext.message('Login Successful', 'Login Successful'+user_auth_info_response.message+')');
                    }
                    else {
                        if (callback) (callback)(false, 'Login Failed: '+json_response.message);
                        else FrontSuite.util.ext.message('Login Failed', 'Login Failed: '+json_response.message);
                    }
                },
                failure: function(response, opts) {
                    if (callback) (callback)(false, 'Login Failed: ' + response.status);
                    else FrontSuite.util.ext.message('Login Failed', 'Login Failed: ' + response.status);
                }
            });
        },
        failure: function(response, opts) {
            if (callback) (callback)(false, 'Login Failed: ' + response.status);
            else FrontSuite.util.ext.message('Login Failed', 'Login Failed: ' + response.status);
        }
    });
};

FrontSuite.util.ext.register = function (email, password, userData, callback) {
    var apps_urldir             = FrontSuite.options.apps_urldir;
    var client_connection_token = FrontSuite.connection.client_connection_token;
    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/auth/reserve_user',
        method    : 'POST',
        params    : {'email' : email,
                     'client_connection_token': client_connection_token,
                     'recaptcha_response_field': userData.recaptcha_response_field,
                     'recaptcha_challenge_field': userData.recaptcha_challenge_field},
        autoAbort : false,
        scope     : this,
        success : function(response) {
            var reserve_user_response  = Ext.JSON.decode(response.responseText);
            if (reserve_user_response.success == false) {
                if (callback) (callback)(false, 'Registration Failed: '+reserve_user_response.message);
                else FrontSuite.util.ext.message('Registration Failed', 'Registration Failed: ('+reserve_user_response.message+')');
            }
            else {
                var user_salt           = reserve_user_response.user_salt;
                var algorithm           = reserve_user_response.algorithm;
                var algorithm_option    = reserve_user_response.algorithm_option;
                var username            = reserve_user_response.username;
//console.log(reserve_user_response);
                var password_hash       = FrontSuite.util.makePasswordHash(algorithm, algorithm_option, password, user_salt);
                var crypt_password_hash = FrontSuite.util.encrypt(client_connection_token, password_hash);   // use the client_connection_token to encrypt the password_hash
                userData.username = username;
                userData.email    = email;
                userData.x        = crypt_password_hash;
                if (userData.password) delete userData.password;
//console.log(userData);
                Ext.Ajax.request({
                    url       : apps_urldir+'/sitefront/front-framework/api.php/service/auth/register',
                    method    : 'POST',
                    params    : userData,
                    autoAbort : false,
                    scope     : this,
                    success   : function(response) {
                        var registration_response  = Ext.JSON.decode(response.responseText);
                        if (registration_response.success == true) {
                            if (callback) (callback)(true, registration_response.message);
                            else FrontSuite.util.ext.message('Registration Success', 'The First Part of Registration has been Successful');
                        }
                        else {
                            if (callback) (callback)(false, 'Registration Failed: '+registration_response.message);
                            else FrontSuite.util.ext.message('Registration Failed', 'Registration Failed: ('+registration_response.message+')');
                        }
                    },
                    failure: function(response, opts) {
                        if (callback) (callback)(false, 'Registration Failed (due to technical malfunction): ('+response.status+')');
                        else FrontSuite.util.ext.message('Registration Failed', 'Registration Failed (due to technical malfunction): ('+response.status+')');
                    }
                });
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)(false, 'Registration Failed: ' + response.status);
            else FrontSuite.util.ext.message('Registration Failed', 'Registration Failed: '+response.status);
        }
    });
};

FrontSuite.util.ext.changeGroupOrApp = function (group_id, app_id, callback) {
    var apps_urldir      = FrontSuite.options.apps_urldir;

    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/auth/login',
        params    : {'user_token': FrontSuite.session.user_token,
                     'session_expire_dttm': FrontSuite.session.session_expire_dttm,
                     'auth_token': FrontSuite.session.auth_token,
                     'group_id': group_id,
                     'app_id': app_id,
                     'option': 'authdata'},
        autoAbort : false,
        method    : 'POST',
        scope     : this,
        success : function(response){
            var json_response  = Ext.JSON.decode(response.responseText);
            if (json_response.success) {
                FrontSuite.session.group_id           = json_response.user.group_id;
                FrontSuite.session.app_id             = json_response.user.app_id;
                if (FrontSuite.session.authdata)      delete FrontSuite.session.authdata;
                var session_expire_date = new Date(FrontSuite.session.session_expire_dttm);
                FrontSuite.session.authdata           = json_response;
                if (callback) (callback)(true);
                else FrontSuite.util.ext.message('Group Change Successful', 'Group Change Successful');
            }
            else {
                if (callback) (callback)(false, 'Group Change Failed: '+json_response.message);
                else FrontSuite.util.ext.message('Group Change Failed', 'Group Change Failed: '+json_response.message);
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)(false, 'Group Change Failed: ' + response.status);
            else FrontSuite.util.ext.message('Group Change Failed', 'Group Change Failed: '+response.status);
        }
    });
};

FrontSuite.util.ext.logout = function (callback) {
    var apps_urldir         = FrontSuite.options.apps_urldir;
    var session_expire_dttm = '2038-01-01 00:00:00';
    var session_expire_date = new Date(session_expire_dttm);

    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/auth/logout',
        autoAbort : false,
        method    : 'POST',
        scope     : this,
        success : function(response){
            var json_response  = Ext.JSON.decode(response.responseText);
            if (json_response.success) {
                FrontSuite.session.user_token        = json_response.user_token;
                FrontSuite.session.session_expire_dttm = session_expire_dttm;
                FrontSuite.session.auth_token        = 'xxxxxx';
                FrontSuite.session.group_id          = json_response.user.group_id;
                FrontSuite.session.app_id            = json_response.user.app_id;
                if (FrontSuite.session.authdata)     delete FrontSuite.session.authdata;
                FrontSuite.session.authdata          = json_response;
                if (callback) (callback)(true);
                else FrontSuite.util.ext.message('Sign-Out Successful', 'Sign-Out Successful');
            }
            else {
                if (callback) (callback)(false, 'Sign-Out Failed');
                else FrontSuite.util.ext.message('Sign-Out Failed', 'Sign-Out Failed');
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)(false, 'Sign-Out Failed: ' + response.status);
            else FrontSuite.util.ext.message('Sign-Out Failed', 'Sign-Out Failed: ' + response.status);
        }
    });
};

/**
 * listDatabaseObjects(db_name, table_name, callback) - based on an optional "current" db_name and table_name, return metadata for all db's, tables in the current db, and columns in the current table
 * @param string  db_name    [IN] - (optional) current database name
 * @param string  table_name [IN] - (optional) current table name
 * @param boolean success    [OUT] - whether the call succeeded
 */
FrontSuite.util.ext.listDatabaseObjects = function (db_name, table_name, callback) {
    var apps_urldir         = FrontSuite.options.apps_urldir;
    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/databaseAdmin/listDatabaseObjects',
        params    : {'db_name': db_name, 'table_name': table_name},
        autoAbort : false,
        method    : 'GET',
        scope     : this,
        success : function (response) {
            var json_response  = Ext.JSON.decode(response.responseText);
console.log('listDataObjects()');
console.log(response);
console.log(json_response);
            if (json_response.success) {
                if (callback) (callback)(json_response);
                else FrontSuite.util.ext.message('Successful', 'Successful');
            }
            else {
                if (callback) (callback)(json_response, 'Failed');
                else FrontSuite.util.ext.message('Failed', 'Failed');
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)({}, 'Failed: ' + response.status);
            else FrontSuite.util.ext.message('Failed', 'Failed: ' + response.status);
        }
    });
};

/**
 * put(request, callback) - put/store a text-blob (or a vivified Javascript object) to the key-value store
 * @param string  type       [IN] - (required) a string defining the domain of things stored (keys are unique for each type)
 * @param string  key        [IN] - (required) the key, making the record unique within a 'type'
 * @param string  data       [IN] - the text-blob
 * @param boolean success    [OUT] - whether the call succeeded
 * @param string  message    [OUT] - message about what happened
 */
FrontSuite.util.ext.put = function (request, callback) {
    var apps_urldir         = FrontSuite.options.apps_urldir;
    var encodedData         = (request.data != null && typeof request.data === 'object') ? Ext.encode(request.data) : request.data;
    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/keyStore/put',
        params    : { type: request.type, key: request.key, label: request.label, data: encodedData },
        headers   : { 'Content-Type': 'application/json' },
        autoAbort : false,
        method    : 'PUT',
        scope     : this,
        success : function(response){
            var json_response  = Ext.JSON.decode(response.responseText);
            if (json_response.success) {
                if (callback) (callback)(json_response);
                else FrontSuite.util.ext.message('Successful', 'Successful');
            }
            else {
                if (callback) (callback)(json_response, 'Failed');
                else FrontSuite.util.ext.message('Failed', 'Failed');
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)({}, 'Failed: ' + response.status);
            else FrontSuite.util.ext.message('Failed', 'Failed: ' + response.status);
        }
    });
};

/**
 * get(request, callback) - get/retrieve a text-blob (e.g. a JSON-serialized Javascript object) from the key-value store
 * @param string  type       [IN] - (required) a string defining the domain of things stored (keys are unique for each type)
 * @param string  key        [IN] - (required) the key, making the record unique within a 'type'
 * @param boolean success    [OUT] - whether the call succeeded
 * @param string  data       [OUT] - the text-blob
 */

FrontSuite.util.ext.get = function (request, callback) {
    var apps_urldir         = FrontSuite.options.apps_urldir;
    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/keyStore/get',
        params    : request,
        autoAbort : false,
        method    : 'GET',
        scope     : this,
        success : function(response){
            var json_response  = Ext.JSON.decode(response.responseText);
            if (json_response.success) {
                if (callback) (callback)(json_response);
                else FrontSuite.util.ext.message('Successful', 'Successful');
            }
            else {
                if (callback) (callback)(json_response, 'Failed');
                else FrontSuite.util.ext.message('Failed', 'Failed');
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)({}, 'Failed: ' + response.status);
            else FrontSuite.util.ext.message('Failed', 'Failed: ' + response.status);
        }
    });
};

/**
 * delete(request, callback) - delete/remove a text-blob (e.g. a JSON-serialized Javascript object) from the key-value store
 * @param string  type       [IN] - (required) a string defining the domain of things stored (keys are unique for each type)
 * @param string  key        [IN] - (required) the key, making the record unique within a 'type'
 * @param boolean success    [OUT] - whether the call succeeded
 */

FrontSuite.util.ext.delete = function (request, callback) {
    var apps_urldir         = FrontSuite.options.apps_urldir;
    Ext.Ajax.request({
        url       : apps_urldir+'/sitefront/front-framework/api.php/service/keyStore/delete',
        params    : request,
        autoAbort : false,
        method    : 'DELETE',
        scope     : this,
        success : function(response){
            var json_response  = Ext.JSON.decode(response.responseText);
            if (json_response.success) {
                if (callback) (callback)(json_response);
                else FrontSuite.util.ext.message('Successful', 'Successful');
            }
            else {
                if (callback) (callback)(json_response, 'Failed');
                else FrontSuite.util.ext.message('Failed', 'Failed');
            }
        },
        failure: function(response, opts) {
            if (callback) (callback)({}, 'Failed: ' + response.status);
            else FrontSuite.util.ext.message('Failed', 'Failed: ' + response.status);
        }
    });
};

// ASYNCHRONOUS: slips in a message that fades away
// code based on http://dev.sencha.com/deploy/ext-4.0.0/examples/message-box/msg-box.html
FrontSuite.util.ext.message = function (title, messageText, duration) {
    if (!this.msgContainer) {
        this.msgContainer = Ext.core.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
    }
    if (!duration) duration = 1500;
    var formattedMessageText = Ext.String.format.apply(String, Array.prototype.slice.call(arguments, 1));   // substitute extra args into messageText
    var msgBox = '<div class="msg"><h3>' + title + '</h3><p>' + formattedMessageText + '</p></div>';
    var msgElement = Ext.core.DomHelper.append(this.msgContainer, msgBox, true);
    msgElement.hide();
    msgElement.slideIn('t').ghost('t', {delay: duration, remove: true});
};

// SYNCHRONOUS: Pops up a dialog box
FrontSuite.util.ext.notify = function (args) {
    var message;
    if (Ext.isString(args)) message = args;
    else                    message = args.message;
    Ext.MessageBox.show({
        title   : 'Notification',
        msg     : message,
        buttons : Ext.MessageBox.OK
    });
};

// SYNCHRONOUS: Pops up a dialog box
FrontSuite.util.ext.error = function (args) {
    var message;
    if (Ext.isString(args)) message = args;
    else                    message = args.message;
    if (!message) {
        Ext.MessageBox.show({
            title   : 'Error',
            msg     : 'Error: An error occurred with no error message',
            buttons : Ext.MessageBox.OK
        });
    }
    else if (message.indexOf("\n") > -1) {
        Ext.create("Ext.Window", {
            title   : 'Error Status',
            modal   : true,
            width   : 350,
            layout  : 'fit',
            autoShow : true,
            items: [{
                xtype:    'panel',
                html:      '<pre>Error: ' + message + '</pre>',
                autoScroll : true
            }],
            buttons: [
                { text: 'OK', handler: function (btn) { btn.up('window').destroy(); } }
            ],
            tools: [
                { type: 'maximize', handler: function (event, toolEl, owner, tool) { tool.up('window').maximize(); } },
                { type: 'restore',  handler: function (event, toolEl, owner, tool) { tool.up('window').restore();  } }
            ]
        });
    }
    else {
        Ext.MessageBox.show({
            title   : 'Error',
            msg     : message,
            buttons : Ext.MessageBox.OK
        });
    }
};

